
package com.zdkj.subway.stm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdkj.common.core.constant.CommonConstants;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.ObjectUtils;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.stm.constant.StmTableCommon;
import com.zdkj.subway.stm.dto.in.CommomConfirmInfoDTO;
import com.zdkj.subway.stm.dto.out.SwStTicketPettyAddDTO;
import com.zdkj.subway.stm.entity.*;
import com.zdkj.subway.stm.mapper.SwStConductorSettleMapper;
import com.zdkj.subway.stm.mapper.SwStMarketingTicketOffineSellMapper;
import com.zdkj.subway.stm.mapper.SwStTicketPettyAddDetailsMapper;
import com.zdkj.subway.stm.mapper.SwStTicketPettyAddMapper;
import com.zdkj.subway.stm.service.*;
import com.zdkj.subway.stm.util.BeanUtilsStm;
import com.zdkj.subway.stm.util.DateUtilStm;
import com.zdkj.subway.stm.util.JdbcUtil;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 车站配票与配备用金
 *
 * @author songtuo
 * @date 2020-07-09 14:14:41
 */
@Service
@AllArgsConstructor
public class SwStTicketPettyAddServiceImpl extends ServiceImpl<SwStTicketPettyAddMapper, SwStTicketPettyAdd> implements SwStTicketPettyAddService {

	private static final Logger LOGGER = LoggerFactory.getLogger(SwStTicketPettyAddServiceImpl.class);

    @Autowired
    SwStTicketPettyAddCashDetailsService cashDetailsService;

    @Autowired
    SwStTicketPettyAddDetailsService ticketDetailsService;

    @Resource
    SwStTicketPettyAddMapper stTicketPettyAddMapper;

    private final SwStmStationDataEntryLogService swStmStationDataEntryLogService;

    @Resource
    private SwStConductorSettleMapper swStConductorSettleMapper;


    @Autowired
    SwStMarketingTicketOffineSellService offineSellService;
    @Autowired
    SwStMarketingTicketGroupSellService ticketGroupSellService;
    @Autowired
    SwStMarketingTicketOffineTakeTicketService takeTicketService;

    @Autowired
    SwStMarketingTicketService marketingTicketService;

    @Autowired
    SwStTicketPettyAddDetailsService swStTicketPettyAddDetailsService;

    @Autowired
    SwStTicketPettyAddCashDetailsService swStTicketPettyAddCashDetailsService;

    @Autowired
    SwStMarketingTicketService swStMarketingTicketService;

    @Resource
    SwStTicketPettyAddDetailsMapper swStTicketPettyAddDetailsMapper;

    @Resource
    SwStMarketingTicketOffineSellMapper swStMarketingTicketOffineSellMapper;

    @Override
    @Transactional
    public boolean saveSwStTicketPettyAdd(SwStTicketPettyAddDTO swStTicketPettyAddDTO) {
        //1:给主表添加默认属性
        SwStTicketPettyAdd stTicketPettyAdd = swStTicketPettyAddDTO.getStTicketPettyAdd();
        SwStTicketPettyAdd stTicketPettyAddObj = ObjectUtils.getDefaultObj(SwStTicketPettyAdd.class);
        BeanUtil.copyProperties(stTicketPettyAddObj, stTicketPettyAdd, CopyOptions.create().setIgnoreNullValue(true));
        //2:首次配备用金信息
        List<SwStTicketPettyAddCashDetails> cashDetailsfirst = swStTicketPettyAddDTO.getCashDetailsfirst();
        BeanUtilsStm.buildProperties(cashDetailsfirst);
        //3:首次配票信息
        List<SwStTicketPettyAddDetails> ticketDetailsFirst = swStTicketPettyAddDTO.getTicketDetailsFirst();
        BeanUtilsStm.buildProperties(ticketDetailsFirst);
        if (CollectionUtil.isNotEmpty(cashDetailsfirst)) {
            //首次配备用金如果金额为null过滤掉
            Stream<SwStTicketPettyAddCashDetails> swStTicketPettyAddCashDetailsStream = cashDetailsfirst.stream().filter(x -> x.getSpareAmount() != null);
            BigDecimal sumAmount = swStTicketPettyAddCashDetailsStream.map(x -> x.getSpareAmount()).reduce(new BigDecimal(0d), BigDecimal::add);
            stTicketPettyAdd.setTotalSpareAmount(sumAmount);
        }
        //4:入库主表
        stTicketPettyAdd.setMatchTicketPersion(SecurityUtils.getUser().getNikeName());
        stTicketPettyAdd.setMatchTicketPersionId(SecurityUtils.getUser().getUserCode());
        stTicketPettyAdd.setDeviceOperateNum(BeanUtilsStm.strRemoveBlank(stTicketPettyAdd.getDeviceOperateNum()));
        save(stTicketPettyAdd);
        //5:入库从表 备用金
        if (CollectionUtil.isNotEmpty(cashDetailsfirst)) {
            cashDetailsfirst.forEach(x -> {
                x.setRelationId(stTicketPettyAdd.getId());
                //首次录入类型是0
                x.setType(0);
            });
            cashDetailsService.saveBatch(cashDetailsfirst);
        }
        //入库车票
        if (CollectionUtil.isNotEmpty(ticketDetailsFirst)) {
            ticketDetailsFirst.forEach(x -> {
                x.setRelationId(stTicketPettyAdd.getId());
                //首次录入类型是0
                x.setType(0);
            });
            ticketDetailsService.saveBatch(ticketDetailsFirst);
        }
        return true;
    }

    /**
     * 更新车票备用金信息
     *
     * @param swStTicketPettyAddDTO
     * @return
     */
    @Override
    @Transactional
    public boolean updateSwStTicketPettyAdd(SwStTicketPettyAddDTO swStTicketPettyAddDTO) {
        SwStTicketPettyAdd stTicketPettyAdd = swStTicketPettyAddDTO.getStTicketPettyAdd();
        Integer rid = stTicketPettyAdd.getId();
        if (stTicketPettyAdd != null) {
            SwStTicketPettyAdd swStTicketPettyAddOld = getById(rid);
            //报表差错修改开关为“1”并且合并状态是“1”的
            if("1".equals(swStTicketPettyAddOld.getIsMerge()) && "1".equals(swStTicketPettyAddOld.getReportModifyStatus())) {
                stTicketPettyAdd.setConfirmStatus("1");
            }
        }
        List<SwStTicketPettyAddCashDetails> cashDetailsfirst = swStTicketPettyAddDTO.getCashDetailsfirst();
        List<SwStTicketPettyAddCashDetails> cashDetailsNewAdd = swStTicketPettyAddDTO.getCashDetailsNewAdd();
        List<SwStTicketPettyAddDetails> ticketDetailsFirst = swStTicketPettyAddDTO.getTicketDetailsFirst();
        List<SwStTicketPettyAddDetails> ticketDetailsNewAdd = swStTicketPettyAddDTO.getTicketDetailsNewAdd();
        //从表1：更新备用金信息  值认本次修改后的休息  bao包括本次修改后的新增信息或者删除信息都认
        updateCashDetails(rid, cashDetailsfirst, 0);
        updateCashDetails(rid, cashDetailsNewAdd, 1);
        //从表2：更新车票配票详情
        updateTicketDetails(rid, ticketDetailsFirst, 0);
        updateTicketDetails(rid, ticketDetailsNewAdd, 1);
        //更新主表数据信息
        BigDecimal totalSpareAmount = new BigDecimal(0d);
        if (CollectionUtil.isNotEmpty(cashDetailsfirst)) {
            BigDecimal sumAmount = cashDetailsfirst.stream().map(x -> x.getSpareAmount()).reduce(new BigDecimal(0d), BigDecimal::add);
            totalSpareAmount = totalSpareAmount.add(sumAmount);
        }
        if (CollectionUtil.isNotEmpty(cashDetailsNewAdd)) {
            BigDecimal sumAmount = cashDetailsNewAdd.stream().map(x -> x.getSpareAmount()).reduce(new BigDecimal(0d), BigDecimal::add);
            totalSpareAmount = totalSpareAmount.add(sumAmount);
        }
        stTicketPettyAdd.setTotalSpareAmount(totalSpareAmount);
        stTicketPettyAdd.setDeviceOperateNum(BeanUtilsStm.strRemoveBlank(stTicketPettyAdd.getDeviceOperateNum()));
        stTicketPettyAdd.setConfirmStatus("0");
        updateById(stTicketPettyAdd);

        String workingStartTime = stTicketPettyAdd.getWorkingStartTime();
        //同时修改结算单的确认状态为未确认
        QueryWrapper<SwStConductorSettle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("LINE_CODE", stTicketPettyAdd.getLineCode());
        queryWrapper.eq("STATION_CODE", stTicketPettyAdd.getStationCode());
        queryWrapper.eq("CONDUCTOR_JOB_NO", stTicketPettyAdd.getNsJobNo());
        queryWrapper.eq("DEVICE_OPERATE_NUM", stTicketPettyAdd.getDeviceOperateNum());
        queryWrapper.eq("CONDUCTOR_SHIFTS", stTicketPettyAdd.getNsShift());
		queryWrapper.eq("DEL_FLAG", "0"); //未删除状态
		queryWrapper.eq("APPROVAL_STATUS", "0"); //未提交状态才修改，否则不要动
		queryWrapper.eq("CONFIRM_STATUS", "1"); //已确认状态才修改，否则不要动
        queryWrapper.apply("DATE_FORMAT(WORKING_START_TIME, '%Y-%m-%d') = DATE_FORMAT('"+workingStartTime+"', '%Y-%m-%d')");
        List<SwStConductorSettle> swStConductorSettles = swStConductorSettleMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(swStConductorSettles)) {
            SwStConductorSettle swStConductorSettle = swStConductorSettles.get(0);
            swStConductorSettle.setConfirmStatus("0");
            swStConductorSettleMapper.updateById(swStConductorSettle);
        }
        return true;
    }

    /**
     * 更新车票信息
     *
     * @param rid
     * @param ticketDetailsFirst
     * @param type
     */
    private void updateTicketDetails(Integer rid, List<SwStTicketPettyAddDetails> ticketDetailsFirst, Integer type) {
        if (CollectionUtil.isNotEmpty(ticketDetailsFirst)) {
            List<SwStTicketPettyAddDetails> insertData = new ArrayList<>();
            List<SwStTicketPettyAddDetails> updateData = new ArrayList<>();
            for (SwStTicketPettyAddDetails ticketPettyAddDetails : ticketDetailsFirst) {
                Integer id = ticketPettyAddDetails.getId();
                if (id == null) {
                    insertData.add(ticketPettyAddDetails);
                } else {
                    updateData.add(ticketPettyAddDetails);
                }
            }
            if (CollectionUtil.isNotEmpty(updateData)) {
                ticketDetailsService.updateBatchById(updateData);
            }
            List<SwStTicketPettyAddDetails> orginList = ticketDetailsService.list(new QueryWrapper<SwStTicketPettyAddDetails>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0).eq("TYPE", type));
            List<SwStTicketPettyAddDetails> removeList = new ArrayList<>();
            List<Integer> updateIds = updateData.stream().map(x -> x.getId()).collect(Collectors.toList());
            for (SwStTicketPettyAddDetails ticketPettyAddDetails : orginList) {
                if (!updateIds.contains(ticketPettyAddDetails.getId())) {
                    //2021-10-15 lu修改 配票归还后，再通过编辑操作将票种删除后，归还数据仍然存在该票种。
                    //根据票种、车票名称、开窗张数、归还类型'2'、对应的relationId来进行移除,TODO 这种情况下只能保证车站配票的时候不会录入两条相同的数据
                    String ticketName = ticketPettyAddDetails.getTicketName();//票种
                    String ticketType = ticketPettyAddDetails.getTicketType();//车票名称
                    Integer windowsNum = ticketPettyAddDetails.getWindowsNum();//开窗张数
                    SwStTicketPettyAddDetails returnRemove = ticketDetailsService.getOne(new QueryWrapper<SwStTicketPettyAddDetails>()
                            .eq("RELATION_ID", rid).eq("DEL_FLAG", 0).eq("TYPE", '2')
                            .eq("TICKET_NAME", ticketName).eq("TICKET_TYPE", ticketType).eq("WINDOWS_NUM", windowsNum));
                    if(ObjectUtil.isNotEmpty(returnRemove)){
                        removeList.add(returnRemove);
                    }
                    removeList.add(ticketPettyAddDetails);
                }
				
            }
			
            if (CollectionUtil.isNotEmpty(removeList)) {
                removeList.forEach(x -> x.setDelFlag("1"));
                ticketDetailsService.updateBatchById(removeList);
            }
            if (CollectionUtil.isNotEmpty(insertData)) {
                for (SwStTicketPettyAddDetails insert : insertData) {
                    insert.setRelationId(rid);
                    insert.setCreateTime(LocalDateTime.now());
                    insert.setType(type);
                }
                ticketDetailsService.saveBatch(insertData);
            }
            //2021-07-28 lu改
            //归还后的第一次编辑重新计算开窗张数 查找已归还的数据
            List<SwStTicketPettyAddDetails> oneTypeList2 = ticketDetailsService.list(Wrappers.<SwStTicketPettyAddDetails>lambdaQuery()
                    .eq(SwStTicketPettyAddDetails::getRelationId, rid)
                    .eq(SwStTicketPettyAddDetails::getType, "2")
                    .eq(SwStTicketPettyAddDetails::getDelFlag, "0")
            );			
            
			if(ObjectUtil.isNotEmpty(oneTypeList2)){
				//查询配票类型是 0(第一次配票) 和1的数据（新增配票)  20240314
			    List<SwStTicketPettyAddDetails> orginList0 = ticketDetailsService.list(new QueryWrapper<SwStTicketPettyAddDetails>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0).eq("TYPE", "0"));
			    List<SwStTicketPettyAddDetails> orginList1 = ticketDetailsService.list(new QueryWrapper<SwStTicketPettyAddDetails>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0).eq("TYPE", "1"));
                
				//归还后的第一次编辑重新计算开窗张数
                // 分组统计配票
                List<SwStTicketPettyAddDetails> objects = new ArrayList<>();
                //类型为0的
                Map<String, List<SwStTicketPettyAddDetails>> collectMap = orginList0.stream().collect(Collectors
                        .groupingBy(o -> o.getTicketName() + "_" + o.getTicketType(), Collectors.toList()));
				//类型为1的
                Map<String, List<SwStTicketPettyAddDetails>> collectMap1 = orginList1.stream().collect(Collectors
                        .groupingBy(o -> o.getTicketName() + "_" + o.getTicketType(), Collectors.toList()));
                //类型为2的
                Map<String,List<SwStTicketPettyAddDetails>> countMap2 = oneTypeList2.stream().collect(Collectors
                        .groupingBy(o -> o.getTicketName() + "_" + o.getTicketType(), Collectors.toList()));

                Set<String> keySet2 = countMap2.keySet();
                for (String key : keySet2) {
                    List<SwStTicketPettyAddDetails> swStTicketPettyAddDetailsList = countMap2.get(key);
                    if(CollectionUtil.isNotEmpty(swStTicketPettyAddDetailsList)){
                        //开窗张数
						//有新增配票
                        if(collectMap.containsKey(key)){
                            List<SwStTicketPettyAddDetails> detailsList = collectMap.get(key);
                            int windowsNum = detailsList.stream().mapToInt(SwStTicketPettyAddDetails::getWindowsNum).sum();
                            SwStTicketPettyAddDetails data = swStTicketPettyAddDetailsList.get(0);
                            data.setWindowsNum(windowsNum);
                            objects.add(data);
                        }
						//含有第二次配票
						if(collectMap1.containsKey(key)){
                            List<SwStTicketPettyAddDetails> detailsList = collectMap1.get(key);
                            int windowsNum = detailsList.stream().mapToInt(SwStTicketPettyAddDetails::getWindowsNum).sum();
                            SwStTicketPettyAddDetails data = swStTicketPettyAddDetailsList.get(0);
							if(CollectionUtil.isNotEmpty(objects)){//已经组织过归还数据，从原来数据查找然后再累加
													    
								for(int i=0;i<objects.size();i++){
								    SwStTicketPettyAddDetails object = objects.get(i);
									String ticketType = object.getTicketType();
									String ticketName = object.getTicketName();
									int objectWindowsNum = object.getWindowsNum();
									if(key.equals(ticketName+"_"+ticketType)){//找到匹配的数据
									    object.setWindowsNum(objectWindowsNum+windowsNum);
										break;
									}
								}
							}else{ //从没有组织过数据，直接累加
							    data.setWindowsNum(windowsNum);
                                objects.add(data);
							}
                           
                        }

						
                    }
                }
                if(CollectionUtil.isNotEmpty(objects)){
                    ticketDetailsService.updateBatchById(objects);
                }
            }
        }
    }
	 /**
     * 新增配票时的方法  20240314 仅限于点击操作按钮的“新增配票”方法
     * @param type ===2
     * @param rid
     * @param ticketDetailsFirst
     * @param type
     */
    private void updateTicketDetailsByNewAdd(Integer rid, List<SwStTicketPettyAddDetails> ticketDetailsFirst, Integer type) {
        if (CollectionUtil.isNotEmpty(ticketDetailsFirst)) {
            List<SwStTicketPettyAddDetails> insertData = new ArrayList<>();
            List<SwStTicketPettyAddDetails> updateData = new ArrayList<>();
			//新增配票的情况下，传过来的子表id一定为空
            for (SwStTicketPettyAddDetails ticketPettyAddDetails : ticketDetailsFirst) {
                Integer id = ticketPettyAddDetails.getId();
                if (id == null) {
                    insertData.add(ticketPettyAddDetails);
                } else {
                    updateData.add(ticketPettyAddDetails);
                }
            }
            if (CollectionUtil.isNotEmpty(updateData)) {
                ticketDetailsService.updateBatchById(updateData);
            }
            //查找已经存在的新增配票数据,如果不存在原来配票信息，只保存页面传过来的，如果原来配过新增配票，要进行合并和累加
			List<SwStTicketPettyAddDetails> orginList = ticketDetailsService.list(new QueryWrapper<SwStTicketPettyAddDetails>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0).eq("TYPE", type));
            //类型为1的转换为Map
            Map<String, List<SwStTicketPettyAddDetails>> collectMapHaveConfig = orginList.stream().collect(Collectors
                        .groupingBy(o -> o.getTicketName() + "_" + o.getTicketType(), Collectors.toList()));
						
			List<SwStTicketPettyAddDetails> removeList = new ArrayList<>();
			if(CollectionUtil.isNotEmpty(orginList)){
			    for (SwStTicketPettyAddDetails ticketPettyAddDetails : insertData) {
				    String ticketName = ticketPettyAddDetails.getTicketName();//票种
                    String ticketType = ticketPettyAddDetails.getTicketType();//车票名称
                    Integer windowsNum = ticketPettyAddDetails.getWindowsNum();//开窗张数
					//找到匹配的进行合并，并将原来的数据进行删除
					String key  = ticketName+ "_" +ticketType;
					if(collectMapHaveConfig.containsKey(key)){
					     SwStTicketPettyAddDetails initData = collectMapHaveConfig.get(key).get(0); //根据票种只能找到一条
						 Integer initWindowsNum = initData.getWindowsNum();//开窗张数
						 //Integer initWindowsCloseNum = initData.getWindowsCloseNum();//关窗张数
						 //设置新增票种的基本信息
						 ticketPettyAddDetails.setWindowsNum(windowsNum+initWindowsNum);
						 //ticketPettyAddDetails.setWindowsCloseNum(initWindowsCloseNum);
                         //删除原来的新增配票数据
						 removeList.add(initData);
					}
				}			
			
			}
						
            if (CollectionUtil.isNotEmpty(removeList)) {
                removeList.forEach(x -> x.setDelFlag("1"));
                ticketDetailsService.updateBatchById(removeList);
            }
            if (CollectionUtil.isNotEmpty(insertData)) {
                for (SwStTicketPettyAddDetails insert : insertData) {
                    insert.setRelationId(rid);
                    insert.setCreateTime(LocalDateTime.now());
                    insert.setType(type);
                }
                ticketDetailsService.saveBatch(insertData);
            }
			//更新已经归还的数据信息		
            //2021-07-28 lu改
            //归还后的第一次编辑重新计算开窗张数 查找已归还的数据
            List<SwStTicketPettyAddDetails> oneTypeList2 = ticketDetailsService.list(Wrappers.<SwStTicketPettyAddDetails>lambdaQuery()
                    .eq(SwStTicketPettyAddDetails::getRelationId, rid)
                    .eq(SwStTicketPettyAddDetails::getType, "2")
                    .eq(SwStTicketPettyAddDetails::getDelFlag, "0")
            );			
            
			if(ObjectUtil.isNotEmpty(oneTypeList2)){
				//查询配票类型是 0(第一次配票) 和1的数据（新增配票)  20240314
			    List<SwStTicketPettyAddDetails> orginList0 = ticketDetailsService.list(new QueryWrapper<SwStTicketPettyAddDetails>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0).eq("TYPE", "0"));
			    List<SwStTicketPettyAddDetails> orginList1 = ticketDetailsService.list(new QueryWrapper<SwStTicketPettyAddDetails>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0).eq("TYPE", "1"));
                
				//归还后的第一次编辑重新计算开窗张数
                // 分组统计配票
                List<SwStTicketPettyAddDetails> objects = new ArrayList<>();
                //类型为0的
                Map<String, List<SwStTicketPettyAddDetails>> collectMap = orginList0.stream().collect(Collectors
                        .groupingBy(o -> o.getTicketName() + "_" + o.getTicketType(), Collectors.toList()));
				//类型为1的
                Map<String, List<SwStTicketPettyAddDetails>> collectMap1 = orginList1.stream().collect(Collectors
                        .groupingBy(o -> o.getTicketName() + "_" + o.getTicketType(), Collectors.toList()));
                //类型为2的
                Map<String,List<SwStTicketPettyAddDetails>> countMap2 = oneTypeList2.stream().collect(Collectors
                        .groupingBy(o -> o.getTicketName() + "_" + o.getTicketType(), Collectors.toList()));

                Set<String> keySet2 = countMap2.keySet();
                for (String key : keySet2) {
                    List<SwStTicketPettyAddDetails> swStTicketPettyAddDetailsList = countMap2.get(key);
                    if(CollectionUtil.isNotEmpty(swStTicketPettyAddDetailsList)){
                        //开窗张数
						//有新增配票
                        if(collectMap.containsKey(key)){
                            List<SwStTicketPettyAddDetails> detailsList = collectMap.get(key);
                            int windowsNum = detailsList.stream().mapToInt(SwStTicketPettyAddDetails::getWindowsNum).sum();
                            SwStTicketPettyAddDetails data = swStTicketPettyAddDetailsList.get(0);
                            data.setWindowsNum(windowsNum);
                            objects.add(data);
                        }
						//含有第二次配票
						if(collectMap1.containsKey(key)){
                            List<SwStTicketPettyAddDetails> detailsList = collectMap1.get(key);
                            int windowsNum = detailsList.stream().mapToInt(SwStTicketPettyAddDetails::getWindowsNum).sum();
                            SwStTicketPettyAddDetails data = swStTicketPettyAddDetailsList.get(0);
							if(CollectionUtil.isNotEmpty(objects)){//已经组织过归还数据，从原来数据查找然后再累加
													    
								for(int i=0;i<objects.size();i++){
								    SwStTicketPettyAddDetails object = objects.get(i);
									String ticketType = object.getTicketType();
									String ticketName = object.getTicketName();
									int objectWindowsNum = object.getWindowsNum();
									if(key.equals(ticketName+"_"+ticketType)){//找到匹配的数据
									    object.setWindowsNum(objectWindowsNum+windowsNum);
										break;
									}
								}
							}else{ //从没有组织过数据，直接累加
							    data.setWindowsNum(windowsNum);
                                objects.add(data);
							}
                           
                        }

						
                    }
                }
                if(CollectionUtil.isNotEmpty(objects)){
                    ticketDetailsService.updateBatchById(objects);
                }
            }
        }
    }

    /**
     * 更新备用金信息
     *
     * @param rid
     * @param cashDetailsfirst
     */
    private void updateCashDetails(Integer rid, List<SwStTicketPettyAddCashDetails> cashDetailsfirst, Integer type) {
        if (CollectionUtil.isNotEmpty(cashDetailsfirst)) {
            List<SwStTicketPettyAddCashDetails> insertData = new ArrayList<>();
            List<SwStTicketPettyAddCashDetails> updateData = new ArrayList<>();
            for (SwStTicketPettyAddCashDetails ticketPettyAddCashDetails : cashDetailsfirst) {
                Integer id = ticketPettyAddCashDetails.getId();
                if (id == null) {
                    insertData.add(ticketPettyAddCashDetails);
                } else {
                    updateData.add(ticketPettyAddCashDetails);
                }
            }
            if (CollectionUtil.isNotEmpty(updateData)) {
                cashDetailsService.updateBatchById(updateData);
            }
            List<SwStTicketPettyAddCashDetails> orginList = cashDetailsService.list(new QueryWrapper<SwStTicketPettyAddCashDetails>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0).eq("TYPE", type));
            List<SwStTicketPettyAddCashDetails> removeList = new ArrayList<>();
            List<Integer> updateIds = updateData.stream().map(x -> x.getId()).collect(Collectors.toList());
            for (SwStTicketPettyAddCashDetails ticketPettyAddCashDetails : orginList) {
                if (!updateIds.contains(ticketPettyAddCashDetails.getId())) {
                    removeList.add(ticketPettyAddCashDetails);
                }
            }
            if (CollectionUtil.isNotEmpty(removeList)) {
                removeList.forEach(x -> x.setDelFlag("1"));
                cashDetailsService.updateBatchById(removeList);
            }
            if (CollectionUtil.isNotEmpty(insertData)) {
                for (SwStTicketPettyAddCashDetails insert : insertData) {
                    insert.setType(type);
                    insert.setRelationId(rid);
                    insert.setCreateTime(LocalDateTime.now());
                }
                cashDetailsService.saveBatch(insertData);
            }
        }
    }

    @Override
    @Transactional
    public boolean deleteCascadeById(Integer id){
        //处理删除后营销车票线下售卖同步删除同步
        SwStTicketPettyAdd byId = getById(id);
        if(ObjectUtil.isNotEmpty(byId)){
            String startTime = byId.getWorkingStartTime();
            LocalDateTime localDateTime = DateUtilStm.LocalDateTimeToString(startTime);
            LocalDate date = localDateTime.toLocalDate();
            int hour = localDateTime.getHour();
            if(hour<2){
                date = date.plusDays(-1);//减一天
            }

            //营销车票sql
            SwStMarketingTicket swStMarketingTicket = swStMarketingTicketService.getBaseMapper().selectOne(Wrappers.<SwStMarketingTicket>lambdaQuery()
                    .eq(SwStMarketingTicket::getLineCode, byId.getLineCode())
                    .eq(SwStMarketingTicket::getStationCode, byId.getStationCode())
                    .eq(SwStMarketingTicket::getConductorShifts, byId.getNsShift())
                    .eq(SwStMarketingTicket::getConductorJobNo, byId.getNsJobNo())
                    .eq(SwStMarketingTicket::getOpertorTime,date)
                    .eq(SwStMarketingTicket::getDelFlag, "0"));
            if(ObjectUtil.isNotEmpty(swStMarketingTicket)){
                marketingTicketExistenceProcessing(swStMarketingTicket,null);
            }
        }
        //删除主表
        removeById(id);
        //删除从表
        List<SwStTicketPettyAddCashDetails> cashList = cashDetailsService.list(new QueryWrapper<SwStTicketPettyAddCashDetails>().eq("RELATION_ID", id).eq("DEL_FLAG", 0));
        List<SwStTicketPettyAddDetails> ticketList = ticketDetailsService.list(new QueryWrapper<SwStTicketPettyAddDetails>().eq("RELATION_ID", id).eq("DEL_FLAG", 0));
        if (CollectionUtil.isNotEmpty(cashList)) {
            cashList.forEach(x -> x.setDelFlag(CommonConstants.STATUS_DEL));
            cashDetailsService.updateBatchById(cashList);
        }
        if (CollectionUtil.isNotEmpty(ticketList)) {
            ticketList.forEach(x -> x.setDelFlag(CommonConstants.STATUS_DEL));
            ticketDetailsService.updateBatchById(ticketList);
        }
        return true;
    }

    /**
     * 根据Id 查看详情  用于回显预览
     *
     * @param id
     * @return
     */
    @Override
    public SwStTicketPettyAddDTO queryDetailsByid(Integer id) {
        SwStTicketPettyAddDTO swStTicketPettyAddDTO = new SwStTicketPettyAddDTO();
        SwStTicketPettyAdd swStTicketPettyAdd = getById(id);
//        if(swStTicketPettyAdd.getTotalHandSpareAmount().compareTo(BigDecimal.ZERO) == 0){
//            swStTicketPettyAdd.setTotalHandSpareAmount(swStTicketPettyAdd.getTotalSpareAmount());
//        }
        swStTicketPettyAddDTO.setStTicketPettyAdd(swStTicketPettyAdd);
        List<SwStTicketPettyAddCashDetails> cashList = cashDetailsService.list(new QueryWrapper<SwStTicketPettyAddCashDetails>().eq("RELATION_ID", id).eq("DEL_FLAG", 0));
        List<SwStTicketPettyAddDetails> ticketList = ticketDetailsService.list(new QueryWrapper<SwStTicketPettyAddDetails>().eq("RELATION_ID", id).eq("DEL_FLAG", 0));
        //.orderByAsc("ticket_name","ticket_type")
        if (CollectionUtil.isNotEmpty(cashList)) {
            List<SwStTicketPettyAddCashDetails> cashDetailsFirst = cashList.stream().filter(x -> x.getType() == 0).collect(Collectors.toList());
            List<SwStTicketPettyAddCashDetails> cashDetailsNewAdd = cashList.stream().filter(x -> x.getType() == 1).collect(Collectors.toList());
            List<SwStTicketPettyAddCashDetails> cashDetailsReturn = cashList.stream().filter(x -> x.getType() == 2).collect(Collectors.toList());
            swStTicketPettyAddDTO.setCashDetailsfirst(cashDetailsFirst);
            swStTicketPettyAddDTO.setCashDetailsNewAdd(cashDetailsNewAdd);
            swStTicketPettyAddDTO.setCashDetailsReturn(cashDetailsReturn);
        }
        if (CollectionUtil.isNotEmpty(ticketList)) {
            List<SwStTicketPettyAddDetails> ticketDetailsFirst = ticketList.stream().filter(x -> x.getType() == 0).collect(Collectors.toList());
            List<SwStTicketPettyAddDetails> ticketDetailsNewAdd = ticketList.stream().filter(x -> x.getType() == 1).collect(Collectors.toList());
            List<SwStTicketPettyAddDetails> ticketDetailsReturn = ticketList.stream().filter(x -> x.getType() == 2).collect(Collectors.toList());
            List<SwStTicketPettyAddDetails> listReturn = new ArrayList<>();
            //归还卡顿，造成多条数据，只保留一条
            if(CollectionUtil.isNotEmpty(ticketDetailsReturn)){
                //类型为2的
                Map<String, List<SwStTicketPettyAddDetails>> countMap2 = new LinkedHashMap<>();

                for (SwStTicketPettyAddDetails detail : ticketDetailsReturn) {
                    String key = detail.getTicketName() + "_" + detail.getTicketType();
                    countMap2.computeIfAbsent(key, k -> new ArrayList<>()).add(detail);
                }
//                Map<String,List<SwStTicketPettyAddDetails>> countMap2 = ticketDetailsReturn.stream().collect(Collectors
//                    .groupingBy(o -> o.getTicketName() + "_" + o.getTicketType(), Collectors.toList()));
                Set<String> keySet2 = countMap2.keySet();
                for (String key : keySet2) {
                    List<SwStTicketPettyAddDetails> swStTicketPettyAddDetailsList = countMap2.get(key);
                    if(CollectionUtil.isNotEmpty(swStTicketPettyAddDetailsList)){
                        listReturn.add(swStTicketPettyAddDetailsList.get(0));
                        if(swStTicketPettyAddDetailsList.size() > 1){
                            for (int i = 1; i < swStTicketPettyAddDetailsList.size(); i++) {
                                ticketDetailsService.remove(Wrappers.query(swStTicketPettyAddDetailsList.get(i)));
                            }
                        }
                    }
                }
            }

            ticketSort(ticketDetailsFirst);
            ticketSort(ticketDetailsNewAdd);
            ticketSort(listReturn);

            swStTicketPettyAddDTO.setTicketDetailsFirst(ticketDetailsFirst);
            swStTicketPettyAddDTO.setTicketDetailsNewAdd(ticketDetailsNewAdd);
            swStTicketPettyAddDTO.setTicketDetailsReturn(listReturn);
        }
        return swStTicketPettyAddDTO;
    }

    private void ticketSort(List<SwStTicketPettyAddDetails> detailsList) {
        if(CollectionUtil.isNotEmpty(detailsList)){
            for (SwStTicketPettyAddDetails detail : detailsList) {
                if ("YRP".equals(detail.getTicketType())) {
                    detail.setSort(1);
                } else if ("SRP".equals(detail.getTicketType())) {
                    detail.setSort(2);
                } else if ("ZLLJSRP".equals(detail.getTicketType())) {
                    detail.setSort(3);
                } else {
                    detail.setSort(999);
                }
            }

            Collections.sort(detailsList, new Comparator<SwStTicketPettyAddDetails>() {
                @Override
                public int compare(SwStTicketPettyAddDetails o1, SwStTicketPettyAddDetails o2) {
                    return o1.getSort().compareTo(o2.getSort());
                }
            });
        }
    }

    //新增备用金以及配票明细保存
    @Override
    public boolean addCashAndTicket(SwStTicketPettyAddDTO stTicketPettyAddDTO) {
        if(stTicketPettyAddDTO.getAddType().equals("1")) {
            SwStTicketPettyAdd stTicketPettyAdd = getById(stTicketPettyAddDTO.getStTicketPettyAdd().getId());
            BigDecimal totalSpareAmount = stTicketPettyAdd.getTotalSpareAmount();

            List<SwStTicketPettyAddDetails> ticketDetailsNewAdd = stTicketPettyAddDTO.getTicketDetailsNewAdd();
            List<SwStTicketPettyAddCashDetails> cashDetailsNewAdd = stTicketPettyAddDTO.getCashDetailsNewAdd();
            if (CollectionUtil.isNotEmpty(ticketDetailsNewAdd)) {
                for (SwStTicketPettyAddDetails detail : ticketDetailsNewAdd) {
                    detail.setRelationId(stTicketPettyAdd.getId());
                    detail.setCreateTime(LocalDateTime.now());
                    detail.setType(1);
                }
                swStTicketPettyAddDetailsService.saveBatch(ticketDetailsNewAdd);
            }
            if (CollectionUtil.isNotEmpty(cashDetailsNewAdd)) {
                for (SwStTicketPettyAddCashDetails cashDetails : cashDetailsNewAdd) {
                    cashDetails.setRelationId(stTicketPettyAdd.getId());
                    cashDetails.setCreateTime(LocalDateTime.now());
                    cashDetails.setType(1);
                }
                swStTicketPettyAddCashDetailsService.saveBatch(cashDetailsNewAdd);
                BigDecimal sumAmount = cashDetailsNewAdd.stream().map(x -> x.getSpareAmount()).reduce(new BigDecimal(0d), BigDecimal::add);
                totalSpareAmount = totalSpareAmount.add(sumAmount);
            }
            stTicketPettyAdd.setTotalSpareAmount(totalSpareAmount);
            stTicketPettyAdd.setConfirmStatus("0");
            updateById(stTicketPettyAdd);

            String workingStartTime = stTicketPettyAdd.getWorkingStartTime();

            QueryWrapper<SwStConductorSettle> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("LINE_CODE", stTicketPettyAdd.getLineCode());
            queryWrapper.eq("STATION_CODE", stTicketPettyAdd.getStationCode());
            queryWrapper.eq("CONDUCTOR_JOB_NO", stTicketPettyAdd.getNsJobNo());
            queryWrapper.eq("DEVICE_OPERATE_NUM", stTicketPettyAdd.getDeviceOperateNum());
            queryWrapper.eq("CONDUCTOR_SHIFTS", stTicketPettyAdd.getNsShift());
            queryWrapper.eq("DEL_FLAG", "0"); //未删除状态
		    queryWrapper.eq("APPROVAL_STATUS", "0"); //未提交状态才修改，否则不要动
		    queryWrapper.eq("CONFIRM_STATUS", "1"); //已确认状态才修改，否则不要动

            queryWrapper.apply("DATE_FORMAT(WORKING_START_TIME, '%Y-%m-%d') = DATE_FORMAT('"+workingStartTime+"', '%Y-%m-%d')");
            List<SwStConductorSettle> swStConductorSettles = swStConductorSettleMapper.selectList(queryWrapper);
            if (CollectionUtil.isNotEmpty(swStConductorSettles)) {
                SwStConductorSettle swStConductorSettle = swStConductorSettles.get(0);
                swStConductorSettle.setConfirmStatus("0");
                swStConductorSettleMapper.updateById(swStConductorSettle);
            }
            return true;
        }
        SwStTicketPettyAdd stTicketPettyAdd = stTicketPettyAddDTO.getStTicketPettyAdd();
        Integer rid = stTicketPettyAdd.getId();
        List<SwStTicketPettyAddCashDetails> cashDetailsNewAdd = stTicketPettyAddDTO.getCashDetailsNewAdd();
        List<SwStTicketPettyAddDetails> ticketDetailsNewAdd = stTicketPettyAddDTO.getTicketDetailsNewAdd();
        //更新从表备用金
        updateCashDetails(rid, cashDetailsNewAdd, 1);
        //更新从表车票
        updateTicketDetailsByNewAdd(rid, ticketDetailsNewAdd, 1);
        //更新主表 首次备用金 + 新增的
        List<SwStTicketPettyAddCashDetails> cashDetailsfirst = cashDetailsService.list(new QueryWrapper<SwStTicketPettyAddCashDetails>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0).eq("TYPE", 0));
        BigDecimal totalSpareAmount = new BigDecimal(0d);
        if (CollectionUtil.isNotEmpty(cashDetailsfirst)) {
            BigDecimal sumAmount = cashDetailsfirst.stream().map(x -> x.getSpareAmount()).reduce(new BigDecimal(0d), BigDecimal::add);
            totalSpareAmount = totalSpareAmount.add(sumAmount);
        }
        if (CollectionUtil.isNotEmpty(cashDetailsNewAdd)) {
            BigDecimal sumAmount = cashDetailsNewAdd.stream().map(x -> x.getSpareAmount()).reduce(new BigDecimal(0d), BigDecimal::add);
            totalSpareAmount = totalSpareAmount.add(sumAmount);
        }
        stTicketPettyAdd.setTotalSpareAmount(totalSpareAmount);
        stTicketPettyAdd.setConfirmStatus("0");
        updateById(stTicketPettyAdd);
        //sw_st_conductor_settle
        String workingStartTime = stTicketPettyAdd.getWorkingStartTime();

        QueryWrapper<SwStConductorSettle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("LINE_CODE", stTicketPettyAdd.getLineCode());
        queryWrapper.eq("STATION_CODE", stTicketPettyAdd.getStationCode());
        queryWrapper.eq("CONDUCTOR_JOB_NO", stTicketPettyAdd.getNsJobNo());
        queryWrapper.eq("DEVICE_OPERATE_NUM", stTicketPettyAdd.getDeviceOperateNum());
        queryWrapper.eq("CONDUCTOR_SHIFTS", stTicketPettyAdd.getNsShift());
        queryWrapper.apply("DATE_FORMAT(WORKING_START_TIME, '%Y-%m-%d') = DATE_FORMAT('"+workingStartTime+"', '%Y-%m-%d')");
        List<SwStConductorSettle> swStConductorSettles = swStConductorSettleMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(swStConductorSettles)) {
            SwStConductorSettle swStConductorSettle = swStConductorSettles.get(0);
            swStConductorSettle.setConfirmStatus("0");
            swStConductorSettleMapper.updateById(swStConductorSettle);
        }

        return true;
    }

    /**
     * 归还备用金及车票
     */
    @Override
    @Transactional
    public boolean returnCashAndTickt(SwStTicketPettyAddDTO stTicketPettyAddDTO) {
        SwStTicketPettyAdd stTicketPettyAdd = stTicketPettyAddDTO.getStTicketPettyAdd();
        Integer rid = stTicketPettyAdd.getId();
        boolean isUpdateMarket = false;
        if (stTicketPettyAdd != null) {
            SwStTicketPettyAdd swStTicketPettyAddOld = getById(rid);
            //报表差错修改开关为“1”并且合并状态是“1”的
            if("1".equals(swStTicketPettyAddOld.getIsMerge()) && "1".equals(swStTicketPettyAddOld.getReportModifyStatus())) {
                stTicketPettyAdd.setConfirmStatus("1");
                isUpdateMarket = true;
            }
        }
        List<SwStTicketPettyAddCashDetails> cashDetailsReturn = stTicketPettyAddDTO.getCashDetailsReturn();
        updateCashDetails(rid, cashDetailsReturn, 2);
        List<SwStTicketPettyAddDetails> ticketDetailsReturn = stTicketPettyAddDTO.getTicketDetailsReturn();
        //ticketDetailsReturn.forEach(x -> x.setWindowsNum(0));
        updateTicketDetails(rid, ticketDetailsReturn, 2);
        Map<String, SwStTicketPettyAddDetails> resultMap = ticketDetailsReturn.stream().collect(Collectors.toMap(x -> x.getTicketType(), y -> y));
        //合并配票明细
        List<SwStTicketPettyAddDetails> ticketList = ticketDetailsService.list(new QueryWrapper<SwStTicketPettyAddDetails>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0).eq("TYPE", 0));
        if (ticketList.size()>0) {
            for (SwStTicketPettyAddDetails ticketPettyAddDetails : ticketList) {
                String ticketType = ticketPettyAddDetails.getTicketType();
                if (resultMap.containsKey(ticketType)) {
                    ticketPettyAddDetails.setWindowsCloseNum(resultMap.get(ticketType).getWindowsCloseNum());
                    ticketPettyAddDetails.setInvalidTicketNum(resultMap.get(ticketType).getInvalidTicketNum());
                }
            }
            ticketDetailsService.updateBatchById(ticketList);
        }
        BigDecimal totalHandSpareAmount = new BigDecimal(0d);
        if (CollectionUtil.isNotEmpty(cashDetailsReturn)) {
            BigDecimal sumAmount = cashDetailsReturn.stream().map(x -> x.getSpareAmount()).reduce(new BigDecimal(0d), BigDecimal::add);
            totalHandSpareAmount = totalHandSpareAmount.add(sumAmount);
        }
        //防止并发这里不更新配备用金
        stTicketPettyAdd.setTotalSpareAmount(null);
        stTicketPettyAdd.setTotalHandSpareAmount(totalHandSpareAmount);
        stTicketPettyAdd.setDeviceAttribution("1");
        stTicketPettyAdd.setConfirmStatus("0");
        updateById(stTicketPettyAdd);
		//修噶结算单的状态
		    String workingStartTime = stTicketPettyAdd.getWorkingStartTime();

            QueryWrapper<SwStConductorSettle> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("LINE_CODE", stTicketPettyAdd.getLineCode());
            queryWrapper.eq("STATION_CODE", stTicketPettyAdd.getStationCode());
            queryWrapper.eq("CONDUCTOR_JOB_NO", stTicketPettyAdd.getNsJobNo());
            queryWrapper.eq("DEVICE_OPERATE_NUM", stTicketPettyAdd.getDeviceOperateNum());
            queryWrapper.eq("CONDUCTOR_SHIFTS", stTicketPettyAdd.getNsShift());
            queryWrapper.eq("DEL_FLAG", "0"); //未删除状态
		    queryWrapper.eq("APPROVAL_STATUS", "0"); //未提交状态才修改，否则不要动
		    queryWrapper.eq("CONFIRM_STATUS", "1"); //已确认状态才修改，否则不要动

            queryWrapper.apply("DATE_FORMAT(WORKING_START_TIME, '%Y-%m-%d') = DATE_FORMAT('"+workingStartTime+"', '%Y-%m-%d')");
            List<SwStConductorSettle> swStConductorSettles = swStConductorSettleMapper.selectList(queryWrapper);
            if (CollectionUtil.isNotEmpty(swStConductorSettles)) {
                SwStConductorSettle swStConductorSettle = swStConductorSettles.get(0);
                swStConductorSettle.setConfirmStatus("0");
                swStConductorSettleMapper.updateById(swStConductorSettle);
            }
		//
        if (isUpdateMarket){
            CommomConfirmInfoDTO commomConfirmInfoDTO = new CommomConfirmInfoDTO();
            commomConfirmInfoDTO.setNsJobNo(stTicketPettyAdd.getNsJobNo());
            commomConfirmInfoDTO.setDate(DateUtilStm.stringTolocalDate(stTicketPettyAdd.getWorkingStartTime()));
            commomConfirmInfoDTO.setNsShift(stTicketPettyAdd.getNsShift());
            //调用营销车票确认方法
            saveMarketingTicket(commomConfirmInfoDTO);
        }
        return true;
    }

    @Override
    public SwStTicketPettyAddDTO queryNeedToConfirmData(CommomConfirmInfoDTO confirmInfoDTO) {
        LocalDate date = confirmInfoDTO.getDate();
        String lineCode = SecurityUtils.getUser().getLineCode();
        String stationCode = SecurityUtils.getUser().getStationCode();
        confirmInfoDTO.setNsJobNo(BeanUtilsStm.bomOrJobNoSort(confirmInfoDTO.getNsJobNo()));//售票员工号排序
        List<SwStTicketPettyAdd> data = stTicketPettyAddMapper.selectList(new QueryWrapper<SwStTicketPettyAdd>().lambda().ge(SwStTicketPettyAdd::getWorkingStartTime, date).le(SwStTicketPettyAdd::getWorkingStartTime, date.plusDays(1))
                .eq(SwStTicketPettyAdd::getNsShift, confirmInfoDTO.getNsShift()).eq(SwStTicketPettyAdd::getNsJobNo, confirmInfoDTO.getNsJobNo())
                .eq(SwStTicketPettyAdd::getLineCode,lineCode).eq(SwStTicketPettyAdd::getStationCode,stationCode));
        if (null == data) {
            return null;
        }
        if(data.size()>1){
            throw new RuntimeException("请检查售票员“" + data.get(0).getNsName() + "”在该班次存在" + data.size() + "条配票与配备用金数据！");
        }
        SwStTicketPettyAddDTO swStTicketPettyAddDTO = new SwStTicketPettyAddDTO();
        if(data.size()>0){
            swStTicketPettyAddDTO = queryDetailsByid(data.get(0).getId());
        }
        return swStTicketPettyAddDTO;
    }

    @Override
    public boolean confirmData(Integer id) {
        SwStTicketPettyAdd pettyAdd = new SwStTicketPettyAdd();
        pettyAdd.setId(id);
        //状态确认
        pettyAdd.setConfirmStatus("1");
        updateById(pettyAdd);
        return true;
    }
    //此方法没有其他类调用----前台有调用的地方,归还和预览调用此方法
    @Override
    public List<Map<String, String>> queryTicketType(Integer relationId) {
        //.orderByAsc("ticket_name","ticket_type")
        LambdaQueryWrapper<SwStTicketPettyAddDetails> eq = new QueryWrapper<SwStTicketPettyAddDetails>().lambda().eq(SwStTicketPettyAddDetails::getRelationId, relationId)
                .in(SwStTicketPettyAddDetails::getType, "0","1").eq(SwStTicketPettyAddDetails::getDelFlag,"0");
        List<SwStTicketPettyAddDetails> list = ticketDetailsService.list(eq);
        ticketSort(list);
        //.orderByAsc("ticket_name","ticket_type")
        LambdaQueryWrapper<SwStTicketPettyAddDetails> eq2 = new QueryWrapper<SwStTicketPettyAddDetails>().lambda().eq(SwStTicketPettyAddDetails::getRelationId, relationId)
                .eq(SwStTicketPettyAddDetails::getType, "2").eq(SwStTicketPettyAddDetails::getDelFlag,"0");
        List<SwStTicketPettyAddDetails> list2 = ticketDetailsService.list(eq2);
        ticketSort(list2);
        List<Map<String, String>> result = new ArrayList<>();
        /*if (CollectionUtils.isNotEmpty(list)) {
            Map<String, List<SwStTicketPettyAddDetails>> countMap = list.stream().filter(x -> x != null).filter(x -> StringUtils.isNotBlank(x.getTicketType())).collect(Collectors.groupingBy(x -> x.getTicketType()));
            Set<String> ticketMap = countMap.keySet();
            for (String key : ticketMap) {
                Map<String, String> map = new HashMap<>();
                map.put("ticketType", key);
                map.put("ticketName", countMap.get(key).get(0).getTicketName());
                map.put("ticketUnit", countMap.get(key).get(0).getTicketUnit());
                map.put("ticketValue",String.valueOf(countMap.get(key).get(0).getTicketValue()));
                map.put("windowsNum", countMap.get(key).get(0).getWindowsNum().toString());
                result.add(map);
            }
        }*/
        Map<String, SwStTicketPettyAddDetails> mapKey = new LinkedHashMap<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (SwStTicketPettyAddDetails key : list) {
                if(!mapKey.containsKey(key.getTicketType())){
                    mapKey.put(key.getTicketType(),key);
                }else{
                    SwStTicketPettyAddDetails detail = mapKey.get(key.getTicketType());
                    detail.setWindowsNum(detail.getWindowsNum() + key.getWindowsNum());
                }
            }

            if(CollectionUtils.isNotEmpty(list2)){
                for (SwStTicketPettyAddDetails key2 : list2) {
                    if(!mapKey.containsKey(key2.getTicketType())){
                        mapKey.put(key2.getTicketType(),key2);
                    }else{
                        SwStTicketPettyAddDetails detail = mapKey.get(key2.getTicketType());
                        detail.setWindowsCloseNum(key2.getWindowsCloseNum());
                        detail.setInvalidTicketNum(key2.getInvalidTicketNum());
						detail.setReplaceTicketNum(key2.getReplaceTicketNum());
                        detail.setCashSaleNum(key2.getCashSaleNum());
                        detail.setCashSaleAmount(key2.getCashSaleAmount());
						detail.setPosSaleNum(key2.getPosSaleNum());
                        detail.setPosSaleAmount(key2.getPosSaleAmount());
						//20241025 支付宝微信POS机
						detail.setWechatSaleNum(key2.getWechatSaleNum());
                        detail.setWechatSaleAmount(key2.getWechatSaleAmount());
						detail.setAlipySaleNum(key2.getAlipySaleNum());
                        detail.setAlipySaleAmount(key2.getAlipySaleAmount());
						detail.setPosCardType(key2.getPosCardType());
                        detail.setPosPayType(key2.getPosPayType());
                    }
                }
            }
            for (SwStTicketPettyAddDetails stpd :mapKey.values()){
                Map<String, String> map = new LinkedHashMap<>();
                map.put("ticketType", stpd.getTicketType());
                map.put("ticketName", stpd.getTicketName());
                map.put("ticketUnit", stpd.getTicketUnit());
                map.put("ticketValue",String.valueOf(stpd.getTicketValue()));
                map.put("windowsNum", stpd.getWindowsNum().toString());
                if(stpd.getWindowsCloseNum() != null){
                    map.put("windowsCloseNum", stpd.getWindowsCloseNum().toString());
                }
                if(stpd.getInvalidTicketNum() != null){
                    map.put("invalidTicketNum", stpd.getInvalidTicketNum().toString());
                }
				if(stpd.getReplaceTicketNum() != null){
                    map.put("replaceTicketNum", stpd.getReplaceTicketNum().toString());
                }
                if(stpd.getCashSaleNum() != null){
                    map.put("cashSaleNum", stpd.getCashSaleNum().toString());
                }
                if(stpd.getCashSaleAmount() != null){
                    map.put("cashSaleAmount", stpd.getCashSaleAmount().toString());
                }
				if(stpd.getPosSaleNum() != null){
                    map.put("posSaleNum", stpd.getPosSaleNum().toString());
                }
                if(stpd.getPosSaleAmount() != null){
                    map.put("posSaleAmount", stpd.getPosSaleAmount().toString());
                }
				if(stpd.getWechatSaleNum() != null){
                    map.put("wechatSaleNum", stpd.getWechatSaleNum().toString());
                }
                if(stpd.getWechatSaleAmount() != null){
                    map.put("wechatSaleAmount", stpd.getWechatSaleAmount().toString());
                }
				if(stpd.getAlipySaleNum() != null){
                    map.put("alipySaleNum", stpd.getAlipySaleNum().toString());
                }
                if(stpd.getAlipySaleAmount() != null){
                    map.put("alipySaleAmount", stpd.getAlipySaleAmount().toString());
                }
				if(stpd.getPosCardType() != null){
                    map.put("posCardType", stpd.getPosCardType().toString());
                }
                if(stpd.getPosPayType() != null){
                    map.put("posPayType", stpd.getPosPayType().toString());
                }

                result.add(map);
            }
        }
        return result;
    }

    @Override
    @Transactional
    public boolean saveTicketPettyDataEntryLog(SwStTicketPettyAddDTO swStTicketPettyAddDTO,Integer saveFlag) {
        PigxUser user = SecurityUtils.getUser();
        SwStTicketPettyAdd stTicketPettyAdd = swStTicketPettyAddDTO.getStTicketPettyAdd();
        if (stTicketPettyAdd != null) {
            SwStTicketPettyAdd swStTicketPettyAddOld = getById(stTicketPettyAdd.getId());
            //报表差错修改开关为“1”打开状态下的时候添加到记录表（先添加主表）
            if(swStTicketPettyAddOld != null && "1".equals(swStTicketPettyAddOld.getReportModifyStatus())) {
                swStTicketPettyAddOld.setEntryUpdateJobNo(user.getUserCode());
                swStTicketPettyAddOld.setEntryUpdateJobName(user.getNikeName());
                swStTicketPettyAddOld.setEntryUpdateTime(new Date());
                if(saveFlag == 1){
                    swStTicketPettyAddOld.setSaveLogFlag("1");
                }else if(saveFlag == 2){
                    swStTicketPettyAddOld.setSaveLogFlag("2");
                }
                SwStmStationDataEntryLog swStmStationDataEntryLog = new SwStmStationDataEntryLog();
                swStmStationDataEntryLog.setRelationId(swStTicketPettyAddOld.getId());
                swStmStationDataEntryLog.setLogTableName(StmTableCommon.SW_ST_TICKET_PETTY_ADD);
                swStmStationDataEntryLog.setLogInfo(JSONObject.toJSONString(swStTicketPettyAddOld));
                swStmStationDataEntryLog.setUpdateJobNo(user.getUserCode());
                swStmStationDataEntryLog.setUpdateJobName(user.getNikeName());
                swStmStationDataEntryLog.setUpdateTime(new Date());
                swStmStationDataEntryLogService.save(swStmStationDataEntryLog);
                Integer mainId = swStmStationDataEntryLog.getId();


                List<SwStTicketPettyAddCashDetails> cashDetailsfirst = swStTicketPettyAddDTO.getCashDetailsfirst();
                List<SwStTicketPettyAddCashDetails> cashDetailsNewAdd = swStTicketPettyAddDTO.getCashDetailsNewAdd();
                List<SwStTicketPettyAddCashDetails> cashDetailsReturn = swStTicketPettyAddDTO.getCashDetailsReturn();
                List<SwStTicketPettyAddDetails> ticketDetailsFirst = swStTicketPettyAddDTO.getTicketDetailsFirst();
                List<SwStTicketPettyAddDetails> ticketDetailsNewAdd = swStTicketPettyAddDTO.getTicketDetailsNewAdd();
                List<SwStTicketPettyAddDetails> ticketDetailsReturn = swStTicketPettyAddDTO.getTicketDetailsReturn();
                if (CollectionUtil.isNotEmpty(cashDetailsfirst)) {
                    //报表差错修改开关为“1”打开状态下的时候添加到记录表（先添加主表）
                    if ("1".equals(swStTicketPettyAddOld.getReportModifyStatus())) {
                        //修改之前添加记录表（再添加子表）
                        List<SwStTicketPettyAddCashDetails> swStTicketPettyAddCashDetailsList = cashDetailsService.list(
                                Wrappers.<SwStTicketPettyAddCashDetails>lambdaQuery()
                                        .eq(SwStTicketPettyAddCashDetails::getRelationId, swStTicketPettyAddOld.getId())
                                        .eq(SwStTicketPettyAddCashDetails::getType,0)//首次配备用金
                                        //.eq(SwStTvmCheckDetailCoinChange::getReportModifyStatus, "1")
                                        .eq(SwStTicketPettyAddCashDetails::getDelFlag, 0));

                        swStTicketPettyAddCashDetailsList.stream().forEach(cashDetails -> {
                            cashDetails.setEntryUpdateJobNo(user.getUserCode());
                            cashDetails.setEntryUpdateJobName(user.getNikeName());
                            cashDetails.setEntryUpdateTime(new Date());
                        });
                        SwStmStationDataEntryLog swStmStationDataEntryLogChild = new SwStmStationDataEntryLog();
                        swStmStationDataEntryLogChild.setRelationId(swStTicketPettyAddOld.getId());
                        swStmStationDataEntryLogChild.setLogTableName(StmTableCommon.SW_ST_TICKET_PETTY_ADD_CASH_DETAILS_0);
                        swStmStationDataEntryLogChild.setMainId(mainId);//记录表id
                        swStmStationDataEntryLogChild.setLogInfo(JSONObject.toJSONString(swStTicketPettyAddCashDetailsList));
                        swStmStationDataEntryLogChild.setUpdateJobNo(user.getUserCode());
                        swStmStationDataEntryLogChild.setUpdateJobName(user.getNikeName());
                        swStmStationDataEntryLogChild.setUpdateTime(new Date());
                        swStmStationDataEntryLogService.save(swStmStationDataEntryLogChild);
                    }
                }
                if (CollectionUtil.isNotEmpty(cashDetailsNewAdd)) {
                    //报表差错修改开关为“1”打开状态下的时候添加到记录表（先添加主表）
                    if ("1".equals(swStTicketPettyAddOld.getReportModifyStatus())) {
                        //修改之前添加记录表（再添加子表）
                        List<SwStTicketPettyAddCashDetails> swStTicketPettyAddCashDetailsList = cashDetailsService.list(
                                Wrappers.<SwStTicketPettyAddCashDetails>lambdaQuery()
                                        .eq(SwStTicketPettyAddCashDetails::getRelationId, swStTicketPettyAddOld.getId())
                                        .eq(SwStTicketPettyAddCashDetails::getType,1)//新增配备用金
                                        //.eq(SwStTvmCheckDetailCoinChange::getReportModifyStatus, "1")
                                        .eq(SwStTicketPettyAddCashDetails::getDelFlag, 0));

                        swStTicketPettyAddCashDetailsList.stream().forEach(cashDetails -> {
                            cashDetails.setEntryUpdateJobNo(user.getUserCode());
                            cashDetails.setEntryUpdateJobName(user.getNikeName());
                            cashDetails.setEntryUpdateTime(new Date());
                        });
                        SwStmStationDataEntryLog swStmStationDataEntryLogChild = new SwStmStationDataEntryLog();
                        swStmStationDataEntryLogChild.setRelationId(swStTicketPettyAddOld.getId());
                        swStmStationDataEntryLogChild.setLogTableName(StmTableCommon.SW_ST_TICKET_PETTY_ADD_CASH_DETAILS_1);
                        swStmStationDataEntryLogChild.setMainId(mainId);//记录表id
                        swStmStationDataEntryLogChild.setLogInfo(JSONObject.toJSONString(swStTicketPettyAddCashDetailsList));
                        swStmStationDataEntryLogChild.setUpdateJobNo(user.getUserCode());
                        swStmStationDataEntryLogChild.setUpdateJobName(user.getNikeName());
                        swStmStationDataEntryLogChild.setUpdateTime(new Date());
                        swStmStationDataEntryLogService.save(swStmStationDataEntryLogChild);
                    }
                }
                if (CollectionUtil.isNotEmpty(cashDetailsReturn)) {
                    //报表差错修改开关为“1”打开状态下的时候添加到记录表（先添加主表）
                    if ("1".equals(swStTicketPettyAddOld.getReportModifyStatus())) {
                        //修改之前添加记录表（再添加子表）
                        List<SwStTicketPettyAddCashDetails> swStTicketPettyAddCashDetailsList = cashDetailsService.list(
                                Wrappers.<SwStTicketPettyAddCashDetails>lambdaQuery()
                                        .eq(SwStTicketPettyAddCashDetails::getRelationId, swStTicketPettyAddOld.getId())
                                        .eq(SwStTicketPettyAddCashDetails::getType,2)//归还配备用金
                                        //.eq(SwStTvmCheckDetailCoinChange::getReportModifyStatus, "1")
                                        .eq(SwStTicketPettyAddCashDetails::getDelFlag, 0));

                        swStTicketPettyAddCashDetailsList.stream().forEach(cashDetails -> {
                            cashDetails.setEntryUpdateJobNo(user.getUserCode());
                            cashDetails.setEntryUpdateJobName(user.getNikeName());
                            cashDetails.setEntryUpdateTime(new Date());
                        });
                        SwStmStationDataEntryLog swStmStationDataEntryLogChild = new SwStmStationDataEntryLog();
                        swStmStationDataEntryLogChild.setRelationId(swStTicketPettyAddOld.getId());
                        swStmStationDataEntryLogChild.setLogTableName(StmTableCommon.SW_ST_TICKET_PETTY_ADD_CASH_DETAILS_2);
                        swStmStationDataEntryLogChild.setMainId(mainId);//记录表id
                        swStmStationDataEntryLogChild.setLogInfo(JSONObject.toJSONString(swStTicketPettyAddCashDetailsList));
                        swStmStationDataEntryLogChild.setUpdateJobNo(user.getUserCode());
                        swStmStationDataEntryLogChild.setUpdateJobName(user.getNikeName());
                        swStmStationDataEntryLogChild.setUpdateTime(new Date());
                        swStmStationDataEntryLogService.save(swStmStationDataEntryLogChild);
                    }
                }
                if (CollectionUtil.isNotEmpty(ticketDetailsFirst)) {
                    //报表差错修改开关为“1”打开状态下的时候添加到记录表（先添加主表）
                    if ("1".equals(swStTicketPettyAddOld.getReportModifyStatus())) {
                        //修改之前添加记录表（再添加子表）
                        List<SwStTicketPettyAddDetails> swStTicketPettyAddDetailsList = ticketDetailsService.list(
                                Wrappers.<SwStTicketPettyAddDetails>lambdaQuery()
                                        .eq(SwStTicketPettyAddDetails::getRelationId, swStTicketPettyAddOld.getId())
                                        .eq(SwStTicketPettyAddDetails::getType,0)//首次配票
                                        //.eq(SwStTvmCheckDetailCoinChange::getReportModifyStatus, "1")
                                        .eq(SwStTicketPettyAddDetails::getDelFlag, 0));

                        swStTicketPettyAddDetailsList.stream().forEach(pettyAddDetails -> {
                            pettyAddDetails.setEntryUpdateJobNo(user.getUserCode());
                            pettyAddDetails.setEntryUpdateJobName(user.getNikeName());
                            pettyAddDetails.setEntryUpdateTime(new Date());
                        });
                        SwStmStationDataEntryLog swStmStationDataEntryLogChild = new SwStmStationDataEntryLog();
                        swStmStationDataEntryLogChild.setRelationId(swStTicketPettyAddOld.getId());
                        swStmStationDataEntryLogChild.setLogTableName(StmTableCommon.SW_ST_TICKET_PETTY_ADD_DETAILS_0);
                        swStmStationDataEntryLogChild.setMainId(mainId);//记录表id
                        swStmStationDataEntryLogChild.setLogInfo(JSONObject.toJSONString(swStTicketPettyAddDetailsList));
                        swStmStationDataEntryLogChild.setUpdateJobNo(user.getUserCode());
                        swStmStationDataEntryLogChild.setUpdateJobName(user.getNikeName());
                        swStmStationDataEntryLogChild.setUpdateTime(new Date());
                        swStmStationDataEntryLogService.save(swStmStationDataEntryLogChild);
                    }
                }
                if (CollectionUtil.isNotEmpty(ticketDetailsNewAdd)) {
                    //报表差错修改开关为“1”打开状态下的时候添加到记录表（先添加主表）
                    if ("1".equals(swStTicketPettyAddOld.getReportModifyStatus())) {
                        //修改之前添加记录表（再添加子表）
                        List<SwStTicketPettyAddDetails> swStTicketPettyAddDetailsList = ticketDetailsService.list(
                                Wrappers.<SwStTicketPettyAddDetails>lambdaQuery()
                                        .eq(SwStTicketPettyAddDetails::getRelationId, swStTicketPettyAddOld.getId())
                                        .eq(SwStTicketPettyAddDetails::getType,1)//新增配票
                                        //.eq(SwStTvmCheckDetailCoinChange::getReportModifyStatus, "1")
                                        .eq(SwStTicketPettyAddDetails::getDelFlag, 0));

                        swStTicketPettyAddDetailsList.stream().forEach(pettyAddDetails -> {
                            pettyAddDetails.setEntryUpdateJobNo(user.getUserCode());
                            pettyAddDetails.setEntryUpdateJobName(user.getNikeName());
                            pettyAddDetails.setEntryUpdateTime(new Date());
                        });
                        SwStmStationDataEntryLog swStmStationDataEntryLogChild = new SwStmStationDataEntryLog();
                        swStmStationDataEntryLogChild.setRelationId(swStTicketPettyAddOld.getId());
                        swStmStationDataEntryLogChild.setLogTableName(StmTableCommon.SW_ST_TICKET_PETTY_ADD_DETAILS_1);
                        swStmStationDataEntryLogChild.setMainId(mainId);//记录表id
                        swStmStationDataEntryLogChild.setLogInfo(JSONObject.toJSONString(swStTicketPettyAddDetailsList));
                        swStmStationDataEntryLogChild.setUpdateJobNo(user.getUserCode());
                        swStmStationDataEntryLogChild.setUpdateJobName(user.getNikeName());
                        swStmStationDataEntryLogChild.setUpdateTime(new Date());
                        swStmStationDataEntryLogService.save(swStmStationDataEntryLogChild);
                    }
                }
                if (CollectionUtil.isNotEmpty(ticketDetailsReturn)) {
                    //报表差错修改开关为“1”打开状态下的时候添加到记录表（先添加主表）
                    if ("1".equals(swStTicketPettyAddOld.getReportModifyStatus())) {
                        //修改之前添加记录表（再添加子表）
                        List<SwStTicketPettyAddDetails> swStTicketPettyAddDetailsList = ticketDetailsService.list(
                                Wrappers.<SwStTicketPettyAddDetails>lambdaQuery()
                                        .eq(SwStTicketPettyAddDetails::getRelationId, swStTicketPettyAddOld.getId())
                                        .eq(SwStTicketPettyAddDetails::getType,2)//归还配票
                                        //.eq(SwStTvmCheckDetailCoinChange::getReportModifyStatus, "1")
                                        .eq(SwStTicketPettyAddDetails::getDelFlag, 0));

                        swStTicketPettyAddDetailsList.stream().forEach(pettyAddDetails -> {
                            pettyAddDetails.setEntryUpdateJobNo(user.getUserCode());
                            pettyAddDetails.setEntryUpdateJobName(user.getNikeName());
                            pettyAddDetails.setEntryUpdateTime(new Date());
                        });
                        SwStmStationDataEntryLog swStmStationDataEntryLogChild = new SwStmStationDataEntryLog();
                        swStmStationDataEntryLogChild.setRelationId(swStTicketPettyAddOld.getId());
                        swStmStationDataEntryLogChild.setLogTableName(StmTableCommon.SW_ST_TICKET_PETTY_ADD_DETAILS_2);
                        swStmStationDataEntryLogChild.setMainId(mainId);//记录表id
                        swStmStationDataEntryLogChild.setLogInfo(JSONObject.toJSONString(swStTicketPettyAddDetailsList));
                        swStmStationDataEntryLogChild.setUpdateJobNo(user.getUserCode());
                        swStmStationDataEntryLogChild.setUpdateJobName(user.getNikeName());
                        swStmStationDataEntryLogChild.setUpdateTime(new Date());
                        swStmStationDataEntryLogService.save(swStmStationDataEntryLogChild);
                    }
                }
            }
        }
        return true;
    }

    public boolean saveMarketingTicket(CommomConfirmInfoDTO confirmInfoDTO){
		/*客值确认时，调动此方法的逻辑
		配票归还数据获取内容：票种，车票名称  金额/次数（单价） 现金售卖张数  现金售卖金额   合计售卖张数、合计售卖金额（两个合计值实际就是现金售卖张数  现金售卖金额）插入到线下正常售卖中
		（只取ticket_name='YXCP'，type='2'  del_flag=0 cash_sale_num>0 and cash_sale_amount>0） ==ticketPrePay

		    2.根据客值确认界面带过来的     线路、站点、售票员操作号、班次、收益日期、售票员工号、删除标识查找营销车票主表数据
		     2.1 主表不存在数据，从配票归还子表内查找ticket_name='YXCP'，type='2'  del_flag=0 标识  cash_sale_num>0,cash_sale_amount>0的记录的数据，直接插入主表和子表，主表的del_flag等默认值要设置上
			 2.2 主表存在，先全部删除线下正常售卖子表（保障之前有删归还等未同步的数据），再从配票归还子表内查找ticket_name='YXCP'，type='2'  del_flag=0 标识 cash_sale_num>0,cash_sale_amount>0的记录的数据 直接插入子表，并重新计算更新主表的总售卖张数和金额，原来的总张数和总金额累加
		    var  ticketPrepay = a ;  //先查询出来归还明细中存在的该售票员售卖的的营销车票
			if(营销车票主表存在){
			      int mainId = 1111;//营销车票主表ID
				  int amount = 0; //营销车票合计数量
				  BigDecimal mooney = new BigDecimal(0.00);  //营销车票合计金额
				  delete 真删，营销车票正常售卖子表数据 保证清除垃圾数据（根据主表ID，查找子表的relation_id 关联删除）

				  if(ticketPrepay.size()>0){  //第一步查询出来的配票明细营销车票对象列表
				    //1. 循环或者执行批量插入营销车票子表（包括营销车票类型、营销现金售卖数量、现金售卖金额以及合计数量和合计金额），//并重新计算主表的总张数和总金额数据（线下取票和团购折扣后的金额+配票金额和数量），
				       for(int ticketPrepay){
					     amout++;
                         money++   //2.  将配票中的营销车票总数和金额  赋值到 amout 和money变量
					   }

					//3. 获取团购和线下取票金额SQL
					 select ifnull(sum(sell_num),0) as amount,ifnull(sum(discount_amount),0) as money  from sw_st_marketing_ticket_group_sell where  relation_id= 1051(mainId) and del_flag='0'

                     select ifnull(sum(ticket_num),0) as amount,ifnull(sum(sell_amount),0) as money  from sw_st_marketing_ticket_offine_take_ticket where relation_id=1051(mainId) and del_flag='0'
                     根据获得的两个表的数量和金额累加再累加到amout 和money中
				  }
				  update 将营销车票主表的确认状态置为1（//实际完成上面那行营销车票确认SQL），主表的总张数和总金额数据（amout,money值）


			}else{//主表不存在  sw_st_marketing_ticket  营销车票主表   sw_st_marketing_ticket_offine_sell 线下正常售卖
			   if(ticketPrepay>0){
			      //插入营销车票主、子表，并更新总张数和总金额数据（总张数和总金额就只算配票中的金额和数量即可）
				   update 将主表的确认状态置为1（//实际完成上面那行营销车票确认SQL），主表的总张数和总金额数据
			   }
			}
		*/
        /*
        		配票归还数据获取内容：票种，车票名称  金额/次数（单价） 现金售卖张数  现金售卖金额   合计售卖张数、合计售卖金额（两个合计值实际就是现金售卖张数  现金售卖金额）插入到线下正常售卖中
		（只取ticket_name='YXCP'，type='2'  del_flag=0 cash_sale_num>0 and cash_sale_amount>0） ==ticketPrePay

		    2.根据客值确认界面带过来的     线路、站点、售票员操作号、班次、收益日期、售票员工号、删除标识查找营销车票主表数据
         */


        String lineCode = SecurityUtils.getUser().getLineCode();
        String stationCode = SecurityUtils.getUser().getStationCode();
        //1.查询配票表的主表
        LocalDate date = confirmInfoDTO.getDate();
        String nsJobNo= confirmInfoDTO.getNsJobNo();
        String nsShift = confirmInfoDTO.getNsShift();
        //售票员工号比较排序
        nsJobNo = BeanUtilsStm.bomOrJobNoSort(nsJobNo);
        SwStTicketPettyAdd pettyAdd = stTicketPettyAddMapper.selectOne(new QueryWrapper<SwStTicketPettyAdd>().lambda()
                .ge(SwStTicketPettyAdd::getWorkingStartTime, date)
                .le(SwStTicketPettyAdd::getWorkingStartTime, date.plusDays(1))
                .eq(SwStTicketPettyAdd::getNsShift, confirmInfoDTO.getNsShift())
                .eq(SwStTicketPettyAdd::getNsJobNo, nsJobNo)//售票员工号排序
                .eq(SwStTicketPettyAdd::getLineCode, lineCode)
                .eq(SwStTicketPettyAdd::getStationCode, stationCode)
                .eq(SwStTicketPettyAdd::getDelFlag, "0"));

        //2.查询出归还明细中存在的该售票员售卖的的营销车票
        //配票归还数据获取内容：票种，车票名称  金额/次数（单价） 现金售卖张数  现金售卖金额   合计售卖张数、合计售卖金额（两个合计值实际就是现金售卖张数  现金售卖金额）插入到线下正常售卖中
        if(pettyAdd != null) {

            SwStMarketingTicket marketingTicket = new SwStMarketingTicket();
            marketingTicket.setLineCode(pettyAdd.getLineCode());
            marketingTicket.setStationCode(pettyAdd.getStationCode());
            marketingTicket.setOpertorTime(DateUtilStm.stringTolocalDate(pettyAdd.getWorkingStartTime()));
            marketingTicket.setConductorName(pettyAdd.getNsName());
            marketingTicket.setConductorId(pettyAdd.getNsId());
            marketingTicket.setConductorJobNo(pettyAdd.getNsJobNo());
            marketingTicket.setConductorShifts(pettyAdd.getNsShift());
            marketingTicket.setDeviceOperateNum(pettyAdd.getDeviceOperateNum());
            marketingTicket.setEntryUpdateJobName(pettyAdd.getEntryUpdateJobName());
            marketingTicket.setEntryUpdateJobNo(pettyAdd.getEntryUpdateJobNo());
            marketingTicket.setEntryUpdateTime(pettyAdd.getEntryUpdateTime());
            //将营销车票主表的确认状态置为1
            marketingTicket.setConfirmStatus("1");
            marketingTicket.setDelFlag("0");

            //营销车票主表 2.根据客值确认界面带过来的     线路、站点、售票员操作号、班次、收益日期、售票员工号、删除标识查找 营销车票主表数据
            SwStMarketingTicket swStMarketingTicket = swStMarketingTicketService.getBaseMapper().selectOne(Wrappers.<SwStMarketingTicket>lambdaQuery()
                    .eq(SwStMarketingTicket::getLineCode, marketingTicket.getLineCode())
                    .eq(SwStMarketingTicket::getStationCode, marketingTicket.getStationCode())
                    .eq(SwStMarketingTicket::getDeviceOperateNum,marketingTicket.getDeviceOperateNum())
                    .eq(SwStMarketingTicket::getConductorShifts, marketingTicket.getConductorShifts())
                    .eq(SwStMarketingTicket::getConductorJobNo, marketingTicket.getConductorJobNo())
                    .eq(SwStMarketingTicket::getOpertorTime, marketingTicket.getOpertorTime())
                    .eq(SwStMarketingTicket::getDelFlag, "0"));

            //根据配票主表ID，查询配票明细表时，只查ticket_name='YXCP'，type='2'  del_flag=0 cash_sale_num>0 and cash_sale_amount>0的数据（过滤掉非营销车票数据）
            List<SwStTicketPettyAddDetails> pettyAddDetails = swStTicketPettyAddDetailsMapper.getTicketPettyAddDetails(pettyAdd.getId());

            ////如果营销车票主表不存在，并且配票明细表不为空    插入主表和子表 并更新总张数和总金额数据（总张数和总金额就只算配票中的金额和数量即可）
            if (swStMarketingTicket == null && com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(pettyAddDetails)) {
                //线下售卖营销车票总张数
                int cashSaleNumTotal = pettyAddDetails.stream().mapToInt(SwStTicketPettyAddDetails::getCashSaleNum).sum();
				
                //线下售卖营销车票总金额
                BigDecimal cashSaleAmountSum = pettyAddDetails.stream().map(SwStTicketPettyAddDetails::getCashSaleAmount).reduce(BigDecimal.ZERO,BigDecimal::add);
                
				// 20240520 线下售卖POS机张数和金额
				 int posSaleNumTotal = pettyAddDetails.stream().mapToInt(SwStTicketPettyAddDetails::getPosSaleNum).sum();
				
                //线下售卖营销车票POS机总金额
                BigDecimal posSaleAmountSum = pettyAddDetails.stream().map(SwStTicketPettyAddDetails::getPosSaleAmount).reduce(BigDecimal.ZERO,BigDecimal::add);
				
				//营销车票主表不存在查bom编号
                SwStConductorSettle conductorSettle = swStConductorSettleMapper.selectOne(Wrappers.<SwStConductorSettle>lambdaQuery()
                        .eq(SwStConductorSettle::getLineCode, SecurityUtils.getUser().getLineCode())
                        .eq(SwStConductorSettle::getStationCode, SecurityUtils.getUser().getStationCode())
                        .eq(SwStConductorSettle::getConductorShifts, confirmInfoDTO.getNsShift())
                        .eq(SwStConductorSettle::getConductorJobNo, confirmInfoDTO.getNsJobNo())
                        .eq(SwStConductorSettle::getSettleTime, confirmInfoDTO.getDate())
                        .eq(SwStConductorSettle::getDelFlag, "0"));

                if(conductorSettle!=null){
                    marketingTicket.setBomCode(conductorSettle.getBomCode());
                }
				// 20250107 现金售卖数量和金额不需要减去POS相关金额
                //marketingTicket.setTotalSellNum(cashSaleNumTotal-posSaleNumTotal);
                //marketingTicket.setTotalSellAmount(cashSaleAmountSum.subtract(posSaleAmountSum));
				marketingTicket.setTotalSellNum(cashSaleNumTotal);
                marketingTicket.setTotalSellAmount(cashSaleAmountSum);
                //插入营销车票主表
                swStMarketingTicketService.save(marketingTicket);
                //获取营销车票主表id
                Integer rid = marketingTicket.getId();

                //处理营销车票从表添加逻辑
                List<SwStMarketingTicketOffineSell> ticketOffineSells = addTicketOffineSells(pettyAddDetails);
                //保存营销车票从表
                if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(ticketOffineSells)) {
                    ticketOffineSells.forEach(x -> x.setRelationId(rid));//营销车票主表id
                    offineSellService.saveBatch(ticketOffineSells);
                }

            }else if(swStMarketingTicket != null) {//营销车票主表存在
                //营销车票存在，配票存在处理
                marketingTicketExistenceProcessing(swStMarketingTicket,pettyAddDetails);
            }


        }else {
            //营销车票sql
            SwStMarketingTicket swStMarketingTicket = swStMarketingTicketService.getBaseMapper().selectOne(Wrappers.<SwStMarketingTicket>lambdaQuery()
                    .eq(SwStMarketingTicket::getLineCode, lineCode)
                    .eq(SwStMarketingTicket::getStationCode, stationCode)
                    .eq(SwStMarketingTicket::getConductorShifts, nsShift)
                    .eq(SwStMarketingTicket::getConductorJobNo, nsJobNo)
                    .eq(SwStMarketingTicket::getOpertorTime, date)
                    .eq(SwStMarketingTicket::getDelFlag, "0"));
            //营销车票存在，配票不存在处理
            if(ObjectUtil.isNotEmpty(swStMarketingTicket)){
                marketingTicketExistenceProcessing(swStMarketingTicket,null);
            }
        }

        return true;
    }

    /**
     * 营销车票存在处理
     * @param swStMarketingTicket
     * @param pettyAddDetails
     * @throws SQLException
     */
    public void marketingTicketExistenceProcessing(SwStMarketingTicket swStMarketingTicket, List<SwStTicketPettyAddDetails> pettyAddDetails){
        List<SwStMarketingTicketGroupSell> groupSellList = ticketGroupSellService.list(new QueryWrapper<SwStMarketingTicketGroupSell>().eq("RELATION_ID", swStMarketingTicket.getId()).eq("DEL_FLAG", 0));
        List<SwStMarketingTicketOffineTakeTicket> offineTakeTicketList = takeTicketService.list(new QueryWrapper<SwStMarketingTicketOffineTakeTicket>().eq("RELATION_ID", swStMarketingTicket.getId()).eq("DEL_FLAG", 0));

        boolean flagDel = false;
        int amount = 0; //营销车票合计数量
        BigDecimal money = new BigDecimal("0.00");  //营销车票合计金额
        // 先全部删除线下正常售卖子表（保障之前有删归还等未同步的数据）
        List<SwStMarketingTicketOffineSell> offineSellList = offineSellService.getBaseMapper().selectList(Wrappers.<SwStMarketingTicketOffineSell>lambdaQuery()
                .eq(SwStMarketingTicketOffineSell::getRelationId, swStMarketingTicket.getId()));
        if(CollectionUtil.isNotEmpty(offineSellList)){
            List<Integer> ids = offineSellList.stream().map(SwStMarketingTicketOffineSell::getId).collect(Collectors.toList());
            swStMarketingTicketOffineSellMapper.deleteBatchIds(ids);
        }
        if(CollectionUtils.isNotEmpty(pettyAddDetails)){
            //处理营销车票从表线下售卖添加逻辑
            List<SwStMarketingTicketOffineSell> ticketOffineSells = addTicketOffineSells(pettyAddDetails);
            //保存营销车票从表线下售卖
            if (CollectionUtils.isNotEmpty(ticketOffineSells)) {
                ticketOffineSells.forEach(x -> x.setRelationId(swStMarketingTicket.getId()));//销车票主表id
                offineSellService.saveBatch(ticketOffineSells);
            }
            //线下售卖营销车票总张数
            int cashSaleNumTotal = pettyAddDetails.stream().mapToInt(SwStTicketPettyAddDetails::getCashSaleNum).sum();
            //线下售卖营销车票总金额
            BigDecimal cashSaleAmountSum = pettyAddDetails.stream().map(SwStTicketPettyAddDetails::getCashSaleAmount).reduce(BigDecimal.ZERO,BigDecimal::add);
            amount += cashSaleNumTotal;
            money = money.add(cashSaleAmountSum);

        }else {
            if(CollectionUtil.isEmpty(groupSellList) && CollectionUtil.isEmpty(offineTakeTicketList)){
                swStMarketingTicketService.removeById(swStMarketingTicket.getId());
                flagDel = true;
            }
        }
        if(!flagDel){
            //团购和线下取票数量和金额 合计
            List<Map<String, Object>> maps = null;
            try {
                maps = JdbcUtil.exeSqlQuery("SELECT IFNULL(SUM(tt.amount),0) amount,IFNULL(SUM(tt.money),0) money from (\n" +
                        "select ifnull(sum(sell_num),0) as amount,ifnull(sum(discount_amount),0) as money  from sw_st_marketing_ticket_group_sell where relation_id = "+swStMarketingTicket.getId()+" and del_flag='0'\n" +
                        " UNION ALL\n" +
                        "select ifnull(sum(ticket_num),0) as amount,ifnull(sum(sell_amount),0) as money  from sw_st_marketing_ticket_offine_take_ticket where relation_id = "+swStMarketingTicket.getId()+" and del_flag='0') tt");
            } catch (SQLException e) {
                e.printStackTrace();
            }
            if(maps!=null){
                BigDecimal b = new BigDecimal(String.valueOf(maps.get(0).get("amount")));
                amount += b.intValue();
                money = money.add((BigDecimal) maps.get(0).get("money"));
            }

            //更新营销车票主表总金额和总数量
            swStMarketingTicket.setTotalSellNum(amount);
            swStMarketingTicket.setTotalSellAmount(money);
            swStMarketingTicketService.updateById(swStMarketingTicket);
        }

    }

    public List<SwStMarketingTicketOffineSell> addTicketOffineSells(List<SwStTicketPettyAddDetails> pettyAddDetails) {
        //线下正常售卖
        List<SwStMarketingTicketOffineSell> ticketOffineSells = new ArrayList<>();
        //保存营销车票从表
        pettyAddDetails.stream().forEach(x -> {
            SwStMarketingTicketOffineSell swStMarketingTicketOffineSell = new SwStMarketingTicketOffineSell();
            swStMarketingTicketOffineSell.setTicketName(x.getTicketType());//票种
            swStMarketingTicketOffineSell.setTicketType(x.getTicketName());//车票名称
            swStMarketingTicketOffineSell.setTicketPrice(x.getTicketValue());//单价
			/* 20250107 现金售卖不需要减去POS 
            swStMarketingTicketOffineSell.setCashSellNum(x.getCashSaleNum()-x.getPosSaleNum());//现金售卖张数
            swStMarketingTicketOffineSell.setCashSellAmount(x.getCashSaleAmount().subtract(x.getPosSaleAmount()));//现金售卖金额
            swStMarketingTicketOffineSell.setTotalSellNum(x.getCashSaleNum()-x.getPosSaleNum());//合计张数
            swStMarketingTicketOffineSell.setTotalSellAmount(x.getCashSaleAmount().subtract(x.getPosSaleAmount()));//合计金额
			*/
			swStMarketingTicketOffineSell.setCashSellNum(x.getCashSaleNum());//现金售卖张数
            swStMarketingTicketOffineSell.setCashSellAmount(x.getCashSaleAmount());//现金售卖金额
            swStMarketingTicketOffineSell.setTotalSellNum(x.getCashSaleNum());//合计张数
            swStMarketingTicketOffineSell.setTotalSellAmount(x.getCashSaleAmount());//合计金额

            swStMarketingTicketOffineSell.setSellTime(x.getCreateTime().toLocalDate());//售卖时间
            swStMarketingTicketOffineSell.setCreateTime(x.getCreateTime());//创建时间
            swStMarketingTicketOffineSell.setUpdateTime(x.getUpdateTime());//数据更新时间
            swStMarketingTicketOffineSell.setEntryUpdateJobNo(x.getEntryUpdateJobNo());//更新人工号
            swStMarketingTicketOffineSell.setEntryUpdateJobName(x.getEntryUpdateJobName());//更新人
            swStMarketingTicketOffineSell.setEntryUpdateTime(x.getEntryUpdateTime());//更新时间
            swStMarketingTicketOffineSell.setReportModifyStatus("0");//报表修改状态默认 0
            swStMarketingTicketOffineSell.setDelFlag("0");
            ticketOffineSells.add(swStMarketingTicketOffineSell);
        });
        return ticketOffineSells;
    }
}
